﻿/*----------------------------------------------------------------
        // Copyright (C) 2016 Rookey
        // 版权所有
        // 开发者：Rookey
        // Email：rookey@yeah.net
        // QQ：3319549098
//----------------------------------------------------------------*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web;
using Rookey.Frame.Common;
using Rookey.Frame.Model.Sys;
using Rookey.Frame.Operate.Base;
using Rookey.Frame.Model.EnumSpace;
using Rookey.Frame.Operate.Base.EnumDef;
using Rookey.Frame.Operate.Base.TempModel;
using Rookey.Frame.UIOperate.Control;
using Rookey.Frame.Base;
using Rookey.Frame.EntityBase;
using Rookey.Frame.Model.Bpm;
using Rookey.Frame.Base.User;
using Rookey.Frame.Base.Set;

namespace Rookey.Frame.UIOperate
{
    /// <summary>
    /// UI框架工厂类
    /// </summary>
    public abstract class UIFrameFactory
    {
        #region 实例化工厂

        /// <summary>
        /// 实例化工厂
        /// </summary>
        /// <param name="moduleId">模块Id</param>
        /// <returns></returns>
        public static UIFrameFactory GetInstance()
        {
            UIFrameFactory factory = new EasyUIFrame();
            if (factory != null)
            {
                factory.Init();
            }
            return factory;
        }
        #endregion

        #region 抽象方法

        #region 初始化

        /// <summary>
        /// 初始化
        /// </summary>
        /// <returns></returns>
        public abstract void Init();

        #endregion

        #region 登录页面

        /// <summary>
        /// 获取登录页面
        /// </summary>
        /// <returns></returns>
        public abstract string GetLoginHTML();

        /// <summary>
        /// 获取弹出登录框页面HTML
        /// </summary>
        /// <returns></returns>
        public abstract string GetDialogLoginHTML();

        #endregion

        #region 主页面

        /// <summary>
        /// 获取前端框架主页面HTML
        /// </summary>
        /// <returns></returns>
        public abstract string GetMainPageHTML();

        /// <summary>
        /// 获取个人设置页面
        /// </summary>
        /// <returns></returns>
        public abstract string GetPersonalSetHTML();

        /// <summary>
        /// 获取修改密码页面
        /// </summary>
        /// <returns></returns>
        public abstract string GetChangePwdHTML();

        /// <summary>
        /// 获取添加快捷菜单页面
        /// </summary>
        /// <returns></returns>
        public abstract string GetAddQuckMenuHTML();

        #endregion

        #region 列表页面

        /// <summary>
        /// 返回网格页面
        /// </summary>
        /// <param name="moduleId">模块Id</param>
        /// <param name="gridType">网格类型</param>
        /// <param name="condition">过滤条件</param>
        /// <param name="where">where过滤条件</param>
        /// <param name="viewId">视图Id</param>
        /// <param name="initModule">针对表单弹出外键选择框，表单原始模块</param>
        /// <param name="initField">针对表单外键弹出框，表单原始字段</param>
        /// <param name="otherParams">其他参数</param>
        /// <param name="detailCopy">明细复制</param>
        /// <param name="filterFields">过滤字段</param>
        /// <param name="menuId">菜单ID，从哪个菜单进来的</param>
        /// <returns></returns>
        public abstract string GetGridHTML(Guid moduleId, DataGridType gridType = DataGridType.MainGrid, string condition = null, string where = null, Guid? viewId = null, string initModule = null, string initField = null, Dictionary<string, object> otherParams = null, bool detailCopy = false, List<string> filterFields = null, Guid? menuId = null);

        /// <summary>
        /// 返回高级搜索页面
        /// </summary>
        /// <param name="moduleId">模块Id</param>
        /// <param name="viewId">视图Id</param>
        /// <returns></returns>
        public abstract string GetAdvanceSearchHTML(Guid moduleId, Guid? viewId);

        /// <summary>
        /// 加载快速编辑视图页面
        /// </summary>
        /// <param name="moduleId">模块Id</param>
        /// <returns></returns>
        public abstract string GetQuickEditViewHTML(Guid moduleId, Guid? gridId);

        /// <summary>
        /// 获取列表视图设置页面
        /// </summary>
        /// <param name="moduleId">模块Id</param>
        /// <returns></returns>
        public abstract string GetGridSetHTML(Guid moduleId);

        /// <summary>
        /// 获取附属模块设置页面
        /// </summary>
        /// <param name="moduleId">模块Id</param>
        /// <returns></returns>
        public abstract string GetAttachModuleSetHTML(Guid moduleId);

        #endregion

        #region 表单页面

        /// <summary>
        /// 获取通用表单页面HTML
        /// </summary>
        /// <param name="moduleId">模块Id</param>
        /// <param name="id">记录Id</param>
        /// <param name="gridId">为网格表单编辑模式的网格Id</param>
        /// <param name="copyId">复制时被复制的记录Id</param>
        /// <param name="showTip">是否显示表单tip按钮</param>
        /// <param name="todoTaskId">待办任务ID</param>
        /// <param name="formId">表单ID</param>
        /// <returns></returns>
        public abstract string GetEditFormHTML(Guid moduleId, Guid? id, string gridId = null, Guid? copyId = null, bool showTip = false, Guid? todoTaskId = null, Guid? formId = null);

        /// <summary>
        /// 获取通用查看表单页面HTML
        /// </summary>
        /// <param name="moduleId">模块Id</param>
        /// <param name="id">记录Id</param>
        /// <param name="gridId">明细网格Id</param>
        /// <param name="fromEditPageFlag">从编辑页面点击查看按钮标识</param>
        /// <param name="isRecycle">是否来自回收站</param>
        /// <param name="showTip">是否显示表单tip按钮</param>
        /// <param name="formId">表单ID</param>        /// <returns></returns>
        public abstract string GetViewFormHTML(Guid moduleId, Guid id, string gridId = null, string fromEditPageFlag = null, bool isRecycle = false, bool showTip = false, Guid? formId = null);

        /// <summary>
        /// 多文件上传表单HTML
        /// </summary>
        /// <param name="moduleId">模块Id</param>
        /// <returns></returns>
        public abstract string GetUploadMitiFileHTML(Guid? moduleId);

        /// <summary>
        /// 获取编辑字段页面
        /// </summary>
        /// <param name="moduleId">模块Id</param>
        /// <param name="fieldName">字段名称</param>
        /// <param name="recordId">记录Id</param>
        /// <returns></returns>
        public abstract string GetEditFieldHTML(Guid moduleId, string fieldName, Guid recordId);

        /// <summary>
        /// 获取批量编辑页面
        /// </summary>
        /// <param name="moduleId">模块Id</param>
        /// <param name="selectRecords">选择的记录数</param>
        /// <param name="pageRecords">当前页记录数</param>
        /// <returns></returns>
        public abstract string GetBatchEditHTML(Guid moduleId, int selectRecords, int pageRecords);

        /// <summary>
        /// 获取实体导入页面
        /// </summary>
        /// <param name="moduleId">模块Id</param>
        /// <returns></returns>
        public abstract string GetImportModelHTML(Guid moduleId);

        /// <summary>
        /// 获取导出设置页面
        /// </summary>
        /// <param name="moduleId">模块Id</param>
        /// <param name="pc">当前记录数</param>
        /// <returns></returns>
        public abstract string GetExportModelHTML(Guid moduleId, int cc);

        /// <summary>
        /// 获取下拉框数据源设置页面
        /// </summary>
        /// <returns></returns>
        public abstract string GetCombDataSourceSetHTML();

        #endregion

        #region 公共页面

        /// <summary>
        /// 返回选择图标页面HTML
        /// </summary>
        /// <returns></returns>
        public abstract string GetIconSelectHTML();

        /// <summary>
        /// 获取弹出树HTML
        /// </summary>
        /// <param name="moduleId">模块id</param>
        /// <returns></returns>
        public abstract string GetDialogTreeHTML(Guid moduleId);

        #endregion

        #region 特殊页面

        /// <summary>
        /// 设置角色表单页面
        /// </summary>
        /// <param name="roleId">角色Id</param>
        /// <returns></returns>
        public abstract string GetSetRoleFormHTML(Guid roleId);

        /// <summary>
        /// 加载快速编辑角色表单页面
        /// </summary>
        /// <param name="moduleId">模块Id</param>
        /// <param name="roleId">角色Id</param>
        /// <param name="formId">表单Id</param>
        /// <returns></returns>
        public abstract string GetQuickEditFormHTML(Guid moduleId, Guid roleId, Guid? formId);

        /// <summary>
        /// 获取设置用户角色页面
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <returns></returns>
        public abstract string GetSetUserRoleHTML(Guid userId);

        /// <summary>
        /// 获取系统配置页面
        /// </summary>
        /// <returns></returns>
        public abstract string GetWebConfigHTML();

        /// <summary>
        /// 添加通用按钮
        /// </summary>
        /// <param name="moduleId">模块id</param>
        /// <returns></returns>
        public abstract string GetAddCommonBtnHTML(Guid moduleId);

        #endregion

        #region 权限页面

        #region 角色权限

        /// <summary>
        /// 获取设置角色模块权限页面
        /// </summary>
        /// <returns></returns>
        public abstract string GetSetRoleModulePermissionHTML();

        /// <summary>
        /// 获取设置角色权限页面
        /// </summary>
        /// <param name="roleId">角色Id</param>
        /// <returns></returns>
        public abstract string GetSetRolePermissionHTML(Guid? roleId);

        /// <summary>
        /// 获取角色数据权限设置页面
        /// </summary>
        /// <param name="moduleName">模块名称</param>
        /// <param name="roleName">角色名称</param>
        /// <param name="type">数据权限类型</param>
        /// <returns></returns>
        public abstract string GetRoleDataPermissionSetHTML(string moduleName, string roleName, int type);

        /// <summary>
        /// 获取角色字段权限设置页面
        /// </summary>
        /// <param name="moduleName">模块名称</param>
        /// <param name="roleName">角色名称</param>
        /// <param name="type">字段权限类型</param>
        /// <returns></returns>
        public abstract string GetRoleFieldPermissionSetHTML(string moduleName, string roleName, int type);

        #endregion

        #region 用户权限

        /// <summary>
        /// 获取设置用户权限页面
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <returns></returns>
        public abstract string GetSetUserPermissionHTML(Guid? userId);

        /// <summary>
        /// 获取用户数据权限设置页面
        /// </summary>
        /// <param name="moduleName">模块名称</param>
        /// <param name="userId">用户Id</param>
        /// <param name="type">数据权限类型</param>
        /// <returns></returns>
        public abstract string GetUserDataPermissionSetHTML(string moduleName, Guid userId, int type);

        /// <summary>
        /// 获取用户字段权限设置页面
        /// </summary>
        /// <param name="moduleName">模块名称</param>
        /// <param name="userId">用户Id</param>
        /// <param name="type">字段权限类型</param>
        /// <returns></returns>
        public abstract string GetUserFieldPermissionSetHTML(string moduleName, Guid userId, int type);

        #endregion

        #endregion

        #region 桌面页面

        /// <summary>
        /// 获取我的桌面页面
        /// </summary>
        /// <returns></returns>
        public abstract string GetDesktopIndexHTML();

        /// <summary>
        /// 获取通用桌面列表页面
        /// </summary>
        /// <param name="moduleId">模块Id</param>
        /// <param name="top">取前多少条</param>
        /// <param name="sortName">排序字段</param>
        /// <param name="isDesc">是否降序</param>
        /// <returns></returns>
        public abstract string GetDesktopGridHTML(Guid moduleId, int top = 5, string sortName = "Id", bool isDesc = true);

        #endregion

        #region 邮件管理

        /// <summary>
        /// 获取邮件首页
        /// </summary>
        /// <returns></returns>
        public abstract string GetEmailIndexHTML();

        #endregion

        #region 流程页面

        /// <summary>
        /// 获取流程设计页面
        /// </summary>
        /// <returns></returns>
        public abstract string GetFlowDesignHTML();

        /// <summary>
        /// 获取流程画布页面
        /// </summary>
        /// <returns></returns>
        public abstract string GetFlowCanvasHTML();

        /// <summary>
        /// 获取流程节点参数设置页面
        /// </summary>
        /// <param name="workflowId">流程ID</param>
        /// <param name="tagId">节点TagId</param>
        /// <returns></returns>
        public abstract string GetNodeParamSetHTML(Guid workflowId, string tagId);

        /// <summary>
        /// 获取流程连接线参数设置页面
        /// </summary>
        /// <param name="workflowId">流程ID</param>
        /// <param name="tagId">连线TagId</param>
        /// <returns></returns>
        public abstract string GetLineParamSetHTML(Guid workflowId, string tagId);

        /// <summary>
        /// 获取选择回退结点页面
        /// </summary>
        /// <param name="workTodoId">待办ID</param>
        /// <returns></returns>
        public abstract string GetSelectBackNodeHTML(Guid workTodoId);

        #endregion

        #endregion

        #region 静态方法

        /// <summary>
        /// 动态计算表单宽度
        /// </summary>
        /// <param name="moduleId">模块Id</param>
        /// <param name="formName">表单名称</param>
        /// <returns></returns>
        internal static int CalcFormWidth(Guid moduleId, Sys_Form form)
        {
            List<Sys_FormField> formFields = SystemOperate.GetFormField(moduleId, form.Name);
            int hiddenType = (int)ControlTypeEnum.HiddenBox;
            formFields = formFields.Where(x => x.ControlType != hiddenType).ToList();
            int width = 0;
            if (formFields != null && formFields.Count > 0)
            {
                var tabs = formFields.OrderBy(x => x.RowNo).ThenBy(x => x.ColNo).GroupBy(x => x.TabName).ToList();
                foreach (var tab in tabs)
                {
                    var groups = tab.OrderBy(x => x.RowNo).ThenBy(x => x.ColNo).GroupBy(x => x.GroupName).ToList();
                    foreach (var g in groups)
                    {
                        var rows = g.OrderBy(x => x.RowNo).ThenBy(x => x.ColNo).GroupBy(x => x.RowNo).ToList();
                        foreach (var row in rows)
                        {
                            int w = 0;
                            int space = row.ToList().Count * (form.SpaceWidth > 0 ? form.SpaceWidth : 40);
                            foreach (var field in row)
                            {
                                w += (form.LabelWidth > 0 ? form.LabelWidth : 90) + (field.Width.HasValue ? field.Width.Value : (form.InputWidth > 0 ? form.InputWidth : 180));
                            }
                            w += space;
                            if (width < w) width = w;
                        }
                    }
                }
                width += 40;
            }
            return width;
        }

        /// <summary>
        /// 动态计算表单高度
        /// </summary>
        /// <param name="moduleId">模块Id</param>
        /// <param name="formName">表单名称</param>
        /// <returns></returns>
        internal static int CalcFormHeight(Guid moduleId, Sys_Form form)
        {
            int rowRh = ConstDefine.FORM_ROW_HEIGHT;
            List<Sys_FormField> formFields = SystemOperate.GetFormField(moduleId, form.Name);
            int hiddenType = (int)ControlTypeEnum.HiddenBox;
            formFields = formFields.Where(x => x.ControlType != hiddenType).ToList();
            int height = 0;
            if (formFields != null && formFields.Count > 0)
            {
                var tabs = formFields.OrderBy(x => x.RowNo).ThenBy(x => x.ColNo).GroupBy(x => x.TabName).ToList();
                foreach (var tab in tabs)
                {
                    int maxHeight = 0;
                    var groups = tab.OrderBy(x => x.RowNo).ThenBy(x => x.ColNo).GroupBy(x => x.GroupName).ToList();
                    foreach (var group in groups)
                    {
                        var rows = group.OrderBy(x => x.RowNo).ThenBy(x => x.ColNo).GroupBy(x => x.RowNo).ToList();
                        int panelHeight = rows.Count * rowRh + ConstDefine.FORM_PANEL_PADDING * 2;
                        maxHeight += panelHeight;
                    }
                    maxHeight += groups.Count * 3;
                    if (height < maxHeight) height = maxHeight;
                }
            }
            return height;
        }

        /// <summary>
        /// 获取Panel高度
        /// </summary>
        /// <param name="group"></param>
        /// <returns></returns>
        internal static int GetPanelHeight(IGrouping<string, Sys_FormField> group)
        {
            if (group == null || group.ToList().Count == 0) return 0;
            int rowRh = ConstDefine.FORM_ROW_HEIGHT;
            var rows = group.OrderBy(x => x.RowNo).ThenBy(x => x.ColNo).GroupBy(x => x.RowNo).ToList();
            int panelHeight = rows.Count * rowRh + ConstDefine.FORM_PANEL_PADDING * 2;
            return panelHeight;
        }

        /// <summary>
        /// 获取表单panel宽度
        /// </summary>
        /// <param name="group"></param>
        /// <param name="form"></param>
        /// <returns></returns>
        internal static int GetPanelWidth(IGrouping<string, Sys_FormField> group, Sys_Form form)
        {
            if (group == null || group.ToList().Count == 0 || form == null) return 0;
            var rows = group.OrderBy(x => x.RowNo).ThenBy(x => x.ColNo).GroupBy(x => x.RowNo).ToList();
            int width = 0;
            foreach (var row in rows)
            {
                int w = 0;
                int space = row.ToList().Count * (form.SpaceWidth > 0 ? form.SpaceWidth : 40);
                foreach (var field in row)
                {
                    w += (form.LabelWidth > 0 ? form.LabelWidth : 90) + (field.Width.HasValue ? field.Width.Value : (form.InputWidth > 0 ? form.InputWidth : 180));
                }
                w += space;
                if (width < w) width = w;
            }
            return width;
        }

        /// <summary>
        /// 获取编辑模式
        /// </summary>
        /// <param name="module">模块对象</param>
        /// <param name="form">表单对象</param>
        /// <param name="formWidth">表单宽度</param>
        /// <param name="formHeight">表单高度</param>
        /// <returns></returns>
        internal static int GetEditMode(Sys_Module module, Sys_Form form, out int formWidth, out int formHeight)
        {
            formWidth = 500;
            formHeight = 300;
            if (form == null)
                return (int)ModuleEditModeEnum.TabFormEdit;
            if (form.ModuleEditModeOfEnum != ModuleEditModeEnum.None &&
                form.ModuleEditModeOfEnum != ModuleEditModeEnum.PopFormEdit)
                return (int)form.ModuleEditModeOfEnum;
            string errMsg = string.Empty;
            int editMode = form.ModuleEditMode.HasValue ? form.ModuleEditMode.Value : 0;
            bool upW = false; //是否更新表单宽
            bool upH = false; //是否更新表单高
            object updateObj = null; //更新对象
            if (form.Width.HasValue && form.Width.Value > 0)
            {
                formWidth = form.Width.Value;
            }
            else
            {
                formWidth = CalcFormWidth(module.Id, form); //动态计算表单宽
                if (formWidth > ConstDefine.DIALOG_FORM_MAX_WIDTH)
                    formWidth = ConstDefine.DIALOG_FORM_MAX_WIDTH;
                upW = true;
            }
            if (form.Height.HasValue && form.Height.Value > 0)
            {
                formHeight = form.Height.Value;
            }
            else
            {
                formHeight = CalcFormHeight(module.Id, form); //动态计算表单高
                if (formHeight > ConstDefine.DIALOG_FORM_MAX_HEIGHT)
                    formHeight = ConstDefine.DIALOG_FORM_MAX_HEIGHT;
                upH = true;
            }
            if (upW && upH)
                updateObj = new { Width = formWidth, Height = formHeight };
            else if (upW)
                updateObj = new { Width = formWidth };
            else if (upH)
                updateObj = new { Height = formHeight };
            if (upH || upW)
            {
                try
                {
                    //将计算的表单宽度、高度更新到表单对象
                    bool rs = CommonOperate.UpdateRecordsByExpression<Sys_Form>(updateObj, x => x.Id == form.Id, out errMsg);
                    if (rs)
                    {
                        if (upW) form.Width = formWidth;
                        if (upH) form.Height = formHeight;
                    }
                }
                catch { }
            }
            if (editMode == (int)ModuleEditModeEnum.None) //自适应编辑模式
            {
                //高度超出自动转成标签页编辑模式
                if (formHeight > ConstDefine.DIALOG_FORM_MAX_HEIGHT || formWidth > ConstDefine.DIALOG_FORM_MAX_WIDTH ||
                    SystemOperate.HasDetailModule(module.Id) || SystemOperate.HasUserAttachModule(UserInfo.CurrentUserInfo.UserId, module.Id, false))
                {
                    editMode = (int)ModuleEditModeEnum.TabFormEdit;
                }
                else //表单高宽比较小时自动转成弹出框编辑模式
                {
                    editMode = (int)ModuleEditModeEnum.PopFormEdit;
                }
                //当前为明细模块时，如果是tab编辑模式或网格行内编辑模式时自动转成弹出框编辑模式
                if (module.ParentId.HasValue && module.ParentId.Value != Guid.Empty &&
                    (editMode == (int)ModuleEditModeEnum.TabFormEdit || editMode == (int)ModuleEditModeEnum.GridRowBottomFormEdit))
                {
                    editMode = (int)ModuleEditModeEnum.PopFormEdit;
                }
            }
            else if (module.ParentId.HasValue && module.ParentId.Value != Guid.Empty &&
                    (editMode == (int)ModuleEditModeEnum.TabFormEdit || editMode == (int)ModuleEditModeEnum.GridRowBottomFormEdit))
            {
                //当前为明细模块时，如果是tab编辑模式或网格行内编辑模式时自动转成弹出框编辑模式
                editMode = (int)ModuleEditModeEnum.PopFormEdit;
            }
            if (editMode == (int)ModuleEditModeEnum.PopFormEdit)
            {
                //弹出框编辑模式如果有明细或有附属模块则弹出框最大化
                if (SystemOperate.HasDetailModule(module.Id) || SystemOperate.HasUserAttachModule(UserInfo.CurrentUserInfo.UserId, module.Id, false))
                {
                    formWidth = ConstDefine.DIALOG_FORM_MAX_WIDTH;
                    formHeight = ConstDefine.DIALOG_FORM_MAX_HEIGHT;
                }
                else if (module.IsEnableAttachment) //启用附件时增加表单高度
                {
                    formHeight += module.FormAttachDisplayStyleOfEnum == FormAttachDisplayStyleEnum.GridStype ? 200 : 100;
                    if (formHeight > ConstDefine.DIALOG_FORM_MAX_HEIGHT)
                        formHeight = ConstDefine.DIALOG_FORM_MAX_HEIGHT;
                }
                if (formWidth < ConstDefine.DIALOG_FORM_MIN_WIDTH) formWidth = ConstDefine.DIALOG_FORM_MIN_WIDTH;
                if (formHeight < ConstDefine.DIALOG_FORM_MIN_HEIGHT) formHeight = ConstDefine.DIALOG_FORM_MIN_HEIGHT;
            }
            else if (editMode == (int)ModuleEditModeEnum.GridRowBottomFormEdit)
            {
                if (module.IsEnableAttachment) //启用附件时增加表单高度
                {
                    formHeight += module.FormAttachDisplayStyleOfEnum == FormAttachDisplayStyleEnum.GridStype ? 200 : 100;
                }
            }
            return editMode;
        }

        /// <summary>
        /// 取自定义页面html
        /// </summary>
        /// <param name="moduleId">模块Id</param>
        /// <param name="methodName">接口方法名称</param>
        /// <param name="args">参数</param>
        /// <returns></returns>
        internal static string GetCustomerPageHTML(Guid moduleId, string methodName, object[] args)
        {
            try
            {
               object obj = CommonOperate.ExecuteCustomeOperateHandleMethod(moduleId, methodName, args);
               return obj.ObjToStr();
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 获取表单字段的编辑控件的HTML
        /// </summary>
        /// <param name="moduleId">模块Id</param>
        /// <param name="field">表单字段</param>
        /// <param name="sysField">字段对象</param>
        /// <param name="model">该模块记录</param>
        /// <param name="propertyStr">属性字符串</param>
        /// <param name="isSearchForm">是否搜索表单</param>
        /// <param name="linkFields">受当前字段值关联的字段，多个以逗号分隔</param>
        /// <param name="copyModel">被复制的对象</param>
        /// <returns></returns>
        internal static string GetFormFieldInputHTML(Guid moduleId, Sys_FormField field, Sys_Field sysField, object model, bool isSearchForm = false, string linkFields = null, object copyModel = null)
        {
            #region 变量定义
            StringBuilder sb = new StringBuilder();
            Sys_Module module = SystemOperate.GetModuleById(moduleId);
            string errMsg = string.Empty;
            object value = null;
            string foreignModuleName = sysField.ForeignModuleName;
            #endregion
            #region 生成输入控件
            string onchangeString = "onChange:function(newValue,oldValue){if(typeof(OnFieldValueChanged)=='function'){OnFieldValueChanged({moduleId:'" + moduleId + "',moduleName:'" + module.Name + "'},'" + field.Sys_FieldName + "',newValue,oldValue);}}";
            string inputOptions = "data-options=\"tipPosition:'right'";
            if (field.ControlTypeOfEnum != ControlTypeEnum.DialogGrid)
            {
                inputOptions += "," + onchangeString;
            }
            if (!isSearchForm) //非搜索表单
            {
                #region 控件值处理
                //字段权限
                if (model != null) //编辑页面
                {
                    value = CommonOperate.GetModelFieldValueByModel(moduleId, model, sysField.Name);
                    if (!field.IsAllowEdit.HasValue || field.IsAllowEdit == false ||
                        !PermissionOperate.CanEditField(UserInfo.CurrentUserInfo.UserId, moduleId, sysField.Name)) //不允许编辑
                    {
                        inputOptions += ",disabled:true";
                    }
                }
                else //新增页面
                {
                    //当前字段为编码字段
                    if (!string.IsNullOrWhiteSpace(sysField.Name) && SystemOperate.GetBillCodeFieldName(module) == sysField.Name)
                    {
                        string billCode = SystemOperate.GetBillCode(module);
                        if (!string.IsNullOrEmpty(billCode))
                        {
                            value = billCode;
                        }
                    }
                    else //未启用编码规则
                    {
                        value = field.DefaultValue;
                        if (field.ControlType == (int)ControlTypeEnum.TextBox ||
                            field.ControlType == (int)ControlTypeEnum.TextAreaBox)
                        {
                            if (value.ObjToStr().StartsWith("{") && value.ObjToStr().EndsWith("}"))
                            {
                                value = string.Empty;
                            }
                        }
                        if (!field.IsAllowAdd.HasValue || field.IsAllowAdd == false ||
                           !PermissionOperate.CanAddField(UserInfo.CurrentUserInfo.UserId, moduleId, sysField.Name)) //不允许新增
                        {
                            inputOptions += ",disabled:true";
                        }
                        else if (copyModel != null && field.IsAllowCopy.HasValue && field.IsAllowCopy.Value) //字段允许新增并且允许复制并且复制对象不为空
                        {
                            value = CommonOperate.GetModelFieldValueByModel(moduleId, copyModel, sysField.Name);
                        }
                    }
                }
                #endregion
                #region 验证处理
                //必填性验证
                if (field.IsRequired.HasValue && field.IsRequired.Value)
                {
                    inputOptions += ",required:true";
                }
                //字符长度验证
                string validTypeStr = string.Empty;
                if (field.MinCharLen.HasValue && field.MinCharLen.Value > 0 && field.MaxCharLen.HasValue && field.MaxCharLen.Value > 0)
                {
                    validTypeStr = string.Format("'length[{0},{1}]'", field.MinCharLen.Value, field.MaxCharLen.Value);
                }
                else if (field.MinCharLen.HasValue && field.MinCharLen.Value > 0)
                {
                    validTypeStr = string.Format("'minLength[{0}]'", field.MinCharLen.Value);
                }
                else if (field.MaxCharLen.HasValue && field.MaxCharLen.Value > 0)
                {
                    validTypeStr = string.Format("'maxLength:[{0}]'", field.MaxCharLen.Value);
                }
                //其他验证类型
                switch (field.ValidateTypeOfEnum)
                {
                    case ValidateTypeEnum.email:
                        validTypeStr += ",'email'";
                        break;
                    case ValidateTypeEnum.url:
                        validTypeStr = ",'url'";
                        break;
                    case ValidateTypeEnum.intNum:
                        validTypeStr = ",'int'";
                        break;
                    case ValidateTypeEnum.floatNum:
                        validTypeStr = ",'float'";
                        break;
                }
                if (!string.IsNullOrEmpty(validTypeStr))
                {
                    inputOptions += string.Format(",validType:[{0}]", validTypeStr);
                }
                #endregion
            }
            string valueField = field.ValueField;
            string textField = field.TextField;
            string fieldUrl = HttpUtility.UrlDecode(field.UrlOrData);
            #region 外键字段、枚举字段、字典字段处理
            if (field.UrlOrData == null && field.ControlTypeOfEnum == ControlTypeEnum.ComboBox)
            {
                if (SystemOperate.IsForeignField(moduleId, field.Sys_FieldName)) //外键字段
                {
                    fieldUrl = string.Format("/{0}/BindForeignFieldComboData.html?moduleId={1}&fieldName={2}", GlobalConst.ASYNC_DATA_CONTROLLER_NAME, moduleId, field.Sys_FieldName);
                }
                else if (SystemOperate.IsEnumField(moduleId, field.Sys_FieldName)) //枚举字段
                {
                    valueField = "Id";
                    textField = "Name";
                    fieldUrl = string.Format("/{0}/BindEnumFieldData.html?moduleId={1}&fieldName={2}", GlobalConst.ASYNC_DATA_CONTROLLER_NAME, moduleId, field.Sys_FieldName);
                }
                else if (SystemOperate.IsDictionaryBindField(moduleId, field.Sys_FieldName)) //字典绑定字段
                {
                    valueField = "Id";
                    textField = "Name";
                    fieldUrl = string.Format("/{0}/BindDictionaryData.html?moduleId={1}&fieldName={2}", GlobalConst.ASYNC_DATA_CONTROLLER_NAME, moduleId, field.Sys_FieldName);
                }
            }
            #endregion
            string inputWidthStr = "100%";
            Sys_Form form = SystemOperate.GetForm(moduleId, field.Sys_FormName);
            int inputWidth = (field.Width.HasValue ? field.Width.Value : (form.InputWidth > 0 ? form.InputWidth : 180));
            if (!isSearchForm) //字段帮助信息不为空
            {
                if (!string.IsNullOrEmpty(field.FieldHelp))
                    inputWidth -= 26;
                //表单字段数据源右边添加一个添加数据源的按钮
                if (module.Name == "表单字段" && sysField.Name == "UrlOrData")
                    inputWidth -= 26;
                inputWidthStr = inputWidth + "px";
            }
            inputWidthStr += string.Format(";height:{0}px", field.ControlTypeOfEnum == ControlTypeEnum.TextAreaBox ? ConstDefine.FORM_TEXTAREA_CONTROL_HEIGHT : ConstDefine.FORM_CONTROL_HEIGHT);
            #region 控件类型处理
            switch (field.ControlTypeOfEnum)
            {
                case ControlTypeEnum.RichTextBox: //富文本框
                    {
                        #region 富文本框
                        if (!isSearchForm)
                        {
                            sb.Append(" <div style=\"width: 100%;\"><script id=\"" + field.Sys_FieldName + "\" name=\"" + field.Sys_FieldName + "\" type=\"text/plain\">" + value.ObjToStr() + "</script><script type=\"text/javascript\">$(function () {var ud = UE.getEditor('" + field.Sys_FieldName + "');$('#edui224_body').hide();});</script></div>");
                        }
                        else
                        {
                            sb.AppendFormat("<input id=\"{0}\" name=\"{0}\" class=\"easyui-textbox\" value=\"{1}\" style=\"width:{2};\"/>", field.Sys_FieldName, value.ObjToStr(), inputWidthStr);
                        }
                        #endregion
                    }
                    break;
                case ControlTypeEnum.TextAreaBox: //文本域
                case ControlTypeEnum.TextBox: //文本框
                    {
                        #region 文本框、文本域
                        string linkFieldsStr = string.Empty;
                        if (!isSearchForm) //非搜索表单
                        {
                            if (!string.IsNullOrEmpty(field.NullTipText))
                            {
                                inputOptions += string.Format(",prompt:'{0}'", field.NullTipText);
                            }
                            if (field.ControlTypeOfEnum == ControlTypeEnum.TextAreaBox)
                            {
                                inputOptions += ",multiline:true";
                            }
                            if (!string.IsNullOrWhiteSpace(linkFields))
                            {
                                linkFieldsStr = string.Format("linkFields=\"{0}\"", linkFields);
                            }
                        }
                        inputOptions += "\"";
                        sb.AppendFormat("<input id=\"{0}\" name=\"{0}\" class=\"easyui-textbox\" value=\"{1}\" style=\"width:{2};\" {3} {4}/>",
                            field.Sys_FieldName, value.ObjToStr(), inputWidthStr, inputOptions, linkFieldsStr);
                        if (module.Name == "表单字段" && sysField.Name == "UrlOrData")
                        {
                            //添加一个添加数据源的按钮
                            int w = 0;
                            int h = 0;
                            int editMode = GetEditMode(module, form, out w, out h);
                            string btn = string.Format("<a id=\"btn_addSource\" pmode=\"{0}\" class=\"easyui-linkbutton\" iconCls=\"eu-icon-cog\" onclick=\"AddDataSource(this)\" plain=\"true\"></a>", editMode);
                            sb.Append(btn);
                        }
                        #endregion
                    }
                    break;
                case ControlTypeEnum.DialogGrid: //弹出列表框
                case ControlTypeEnum.DialogTree: //弹出选择树
                    {
                        #region 弹出列表
                        string fieldName = field.Sys_FieldName; //字段名
                        Guid foreignModuleId = Guid.Empty; //外键Id
                        string valueStr = value.ObjToStr(); //值
                        string linkAddBtn = string.Empty; //外链按钮
                        Sys_Module foreignModule = null; //外键模块
                        string textStr = string.Empty; //显示Text
                        bool isMutiSelect = field.IsMultiSelect == true && SystemOperate.GetFieldType(module.Id, fieldName) == typeof(String);
                        if (!string.IsNullOrEmpty(foreignModuleName)) //外键字段
                        {
                            foreignModule = SystemOperate.GetModuleByName(foreignModuleName);
                        }
                        if (foreignModule != null) //当前字段是外键字段
                        {
                            //先取当前模块冗余字段值，当冗余字段不存在时从外键模块中取
                            string textFieldName = fieldName.Substring(0, fieldName.Length - 2) + "Name";
                            textStr = CommonOperate.GetModelFieldValueByModel(moduleId, model, textFieldName).ObjToStr();
                            foreignModuleId = foreignModule.Id;
                            if (string.IsNullOrEmpty(fieldUrl))
                            {
                                fieldUrl = field.ControlTypeOfEnum == ControlTypeEnum.DialogGrid ? string.Format("/Page/Grid.html?page=fdGrid&moduleId={0}&initModule={1}&initField={2}", foreignModuleId, HttpUtility.UrlEncode(module.Name), fieldName) :
                                          string.Format("/Page/DialogTree.html?moduleName={0}", HttpUtility.UrlEncode(foreignModuleName));
                                if (isMutiSelect) fieldUrl += "&ms=1";
                            }
                            if (string.IsNullOrEmpty(valueField)) valueField = "Id";
                            if (string.IsNullOrEmpty(textField)) textField = SystemOperate.GetModuleTitleKey(foreignModuleId);
                            if (!string.IsNullOrEmpty(value.ObjToStr()) && string.IsNullOrEmpty(textStr))
                            {
                                object tempObj = CommonOperate.GetEntitiesByFieldOne(foreignModuleId, valueField, value, out errMsg);
                                if (tempObj != null)
                                {
                                    textStr = CommonOperate.GetModelFieldValueByModel(foreignModuleId, tempObj, textField).ObjToStr();
                                }
                            }
                            if (!isSearchForm && field.ControlTypeOfEnum == ControlTypeEnum.DialogGrid && foreignModule.IsAllowLinkAdd && !string.IsNullOrEmpty(foreignModule.TitleKey) && foreignModuleName != module.Name && foreignModuleName != "模块管理") //外键模块允许外链添加
                            {
                                Sys_Form foreignForm = SystemOperate.GetUserForm(UserInfo.CurrentUserInfo.UserId, foreignModuleId);
                                int fw = 0;
                                int fh = 0;
                                int mode = GetEditMode(foreignModule, foreignForm, out fw, out fh);
                                if (mode == (int)ModuleEditModeEnum.PopFormEdit) //弹出编辑模式才允许外链
                                {
                                    inputWidthStr = string.Format("{0}px;height:{1}px", inputWidth - 26, ConstDefine.FORM_CONTROL_HEIGHT);
                                    string tempDataOption = string.Format("moduleId=\"{0}\" moduleName=\"{1}\" editMode=\"2\" editWidth=\"{3}\" editHeight=\"{4}\" linkAdd=\"true\" initField=\"{5}\" linkField=\"{6}\" title=\"新增{7}\"",
                                        foreignModuleId, foreignModuleName, mode, fw, fh, fieldName, foreignModule.TitleKey, foreignModule.Name);
                                    linkAddBtn = string.Format("<a id=\"linkBtnAdd_{0}\" class=\"easyui-linkbutton\" data-options=\"iconCls:'eu-icon-add'\" onclick=\"Add(this)\" plain=\"true\" {1}></a>",
                                        foreignModuleId, tempDataOption);
                                }
                            }
                        }
                        else //非外键字段
                        {
                            if (string.IsNullOrEmpty(valueField)) valueField = "Id";
                            if (string.IsNullOrEmpty(textField)) textField = "Name";
                        }
                        string fieldAttr = string.Format("url=\"{0}\" valueField=\"{1}\" textField=\"{2}\" foreignModuleId=\"{3}\" foreignModuleName=\"{4}\"", fieldUrl, valueField, textField, foreignModuleId, foreignModuleName);
                        if (isMutiSelect) fieldAttr += " ms=\"1\"";
                        if (field.ControlTypeOfEnum == ControlTypeEnum.DialogTree)
                            fieldAttr += " isTree=\"1\"";
                        inputOptions += ",icons: [{iconCls:'eu-icon-search',handler: function(e){SelectDialogData($(e.data.target))}}]";
                        if (!isSearchForm && SystemOperate.IsDetailModule(moduleId) && SystemOperate.GetParentModule(moduleId).Name == foreignModuleName)
                        {
                            if (!inputOptions.Contains("disabled:true"))
                                inputOptions += ",disabled:true\"";
                            if (field.IsAllowAdd.HasValue && field.IsAllowAdd.Value)
                            {
                                fieldAttr += " isParentForeignField=\"1\""; //添加父模块外键字段标识
                            }
                        }
                        inputOptions += "\"";
                        sb.AppendFormat("<input id=\"{0}\" name=\"{0}\" foreignField=\"1\" class=\"easyui-textbox\" value=\"{1}\" textValue=\"{5}\" style=\"width:{2};\" {3} {4}/>",
                           fieldName, value.ObjToStr(), inputWidthStr, fieldAttr, inputOptions, textStr);
                        if (!string.IsNullOrEmpty(linkAddBtn))
                        {
                            sb.Append(linkAddBtn);
                        }
                        #endregion
                    }
                    break;
                case ControlTypeEnum.DateBox: //日期
                case ControlTypeEnum.DateTimeBox: //日期时间型
                    {
                        #region 日期、时间
                        string dateClass = "easyui-datebox";
                        if (field.ControlTypeOfEnum == ControlTypeEnum.DateTimeBox)
                            dateClass = "easyui-datetimebox";
                        inputOptions += "\"";
                        sb.AppendFormat("<input id=\"{0}\" name=\"{0}\" class=\"{1}\" style=\"width:{2};\" value=\"{3}\" {4}/>",
                            field.Sys_FieldName, dateClass, inputWidthStr, value.ObjToStr(), inputOptions);
                        #endregion
                    }
                    break;
                case ControlTypeEnum.NumberBox: //数值输入框
                case ControlTypeEnum.IntegerBox: //整型输入框
                    {
                        #region 整形、数值
                        string tempOption = string.Format("precision:{0}", field.ControlTypeOfEnum == ControlTypeEnum.IntegerBox ? 0 : (sysField.Precision.HasValue && sysField.Precision.Value > 0 ? sysField.Precision.Value : 2));
                        if (field.MinValue.HasValue)
                        {
                            tempOption += string.Format(",min:{0}", field.MinValue.Value);
                        }
                        if (field.MaxValue.HasValue)
                        {
                            tempOption += string.Format(",max:{0}", field.MaxValue.Value);
                        }
                        inputOptions += string.Format(",{0}\"", tempOption);
                        sb.AppendFormat("<input id=\"{0}\" name=\"{0}\" style=\"width:{1};\" class=\"easyui-numberbox\" value=\"{2}\" {3}/>",
                            field.Sys_FieldName, inputWidthStr, value.ObjToStr(), inputOptions);
                        #endregion
                    }
                    break;
                case ControlTypeEnum.SingleCheckBox: //单选checkbox
                    {
                        #region 单选checkbox框
                        string v = value == null ? string.Empty : (value.GetType() == typeof(Boolean) ? (value.ObjToBool() ? "1" : "0") : value.ObjToStr());
                        string onchangeStr = "onchanged=\"function(){if(typeof(OnFieldValueChanged)=='function'){OnFieldValueChanged({moduleId:'" + moduleId + "',moduleName:'" + module.Name + "'},'" + field.Sys_FieldName + "');}}\"";
                        sb.AppendFormat("<input id=\"{0}\" name=\"{0}\"  type=\"checkbox\" value=\"{1}\" {2} {3}/>",
                            field.Sys_FieldName, v, v == "1" ? "checked=\"checked\"" : string.Empty, onchangeStr);
                        #endregion
                    }
                    break;
                case ControlTypeEnum.MutiCheckBox: //多选checkbox
                    {
                        #region 多选checkbox框
                        bool isAllowEdit = model != null ? field.IsAllowEdit.HasValue || field.IsAllowEdit.Value :
                                          field.IsAllowAdd.HasValue && field.IsAllowAdd.Value;
                        string html = MvcExtensions.CreateMutiCheckbox(field.Sys_FieldName, field.TextField, field.ValueField, value.ObjToStr(), isAllowEdit);
                        sb.Append(html);
                        #endregion
                    }
                    break;
                case ControlTypeEnum.RadioList: //单选框组
                    {
                        #region 单选框组
                        sb.AppendFormat("<input id=\"{0}\" name=\"{0}\" onchanged=\"OnFieldValueChanged\" type=\"radio\" style=\"width:{1};\" value=\"{2}\"/>",
                            field.Sys_FieldName, inputWidthStr, value.ObjToStr().ToLower());
                        #endregion
                    }
                    break;
                case ControlTypeEnum.ComboBox: //下拉框
                case ControlTypeEnum.ComboTree: //下拉树
                    {
                        #region 下拉框/下拉树
                        Sys_Module foreignModule = SystemOperate.GetModuleByName(foreignModuleName);
                        string className = "easyui-combobox";
                        string loadFilterElseStr = string.Empty;
                        if (field.ControlTypeOfEnum == ControlTypeEnum.ComboTree)
                        {
                            className = "easyui-combotree";
                            if (string.IsNullOrEmpty(valueField)) valueField = "id";
                            if (string.IsNullOrEmpty(textField)) textField = "text";
                            if (fieldUrl == null && foreignModule != null)
                            {
                                fieldUrl = string.Format("/{0}/GetTreeByNode.html?moduleId={1}", GlobalConst.ASYNC_DATA_CONTROLLER_NAME, foreignModule.Id);
                            }
                            loadFilterElseStr = " else {if(typeof (data)== 'string'){var tempData=eval('(' + data + ')');return tempData;} else{var arr=[];arr.push(data);return arr;}}";
                            inputOptions += ",delay:300,editable:true,keyHandler:{query:function(q){QueryComboTree(q, '" + sysField.Name + "');}}";
                        }
                        else
                        {
                            if (string.IsNullOrEmpty(valueField)) valueField = "Id";
                            if (string.IsNullOrEmpty(textField))
                            {
                                string foreignTitleKey = foreignModule == null ? null : SystemOperate.GetModuleTitleKey(foreignModule.Id);
                                textField = string.IsNullOrWhiteSpace(foreignTitleKey) ? "Name" : foreignTitleKey;
                            }
                            loadFilterElseStr = " else {if(typeof (data)== 'string'){var tempData=eval('(' + data + ')');return tempData;} else{return data;}}";
                        }
                        if (fieldUrl != null && fieldUrl.StartsWith("[{") && fieldUrl.EndsWith("}]")) //下拉数据固定data
                        {
                            inputOptions += string.Format(",valueField:'{0}',textField:'{1}',data:{2}", valueField, textField, fieldUrl);
                        }
                        else //从URL取数据
                        {
                            inputOptions += string.Format(",valueField:'{0}',textField:'{1}',url:'{2}'", valueField, textField, fieldUrl.ObjToStr());
                        }
                        inputOptions += ",onLoadSuccess:function(){if(typeof(OnFieldLoadSuccess)=='function'){ OnFieldLoadSuccess('" + sysField.Name + "','" + valueField + "','" + textField + "');}}";
                        inputOptions += ",onSelect:function(record){if(typeof(OnFieldSelect)=='function'){OnFieldSelect(record,'" + sysField.Name + "','" + valueField + "','" + textField + "');}}";
                        inputOptions += ",loadFilter:function(data,parent){if(typeof(OnLoadFilter)=='function'){return OnLoadFilter('" + sysField.Name + "','" + valueField + "','" + textField + "',data,parent);}" + loadFilterElseStr + "}";
                        inputOptions += ",onLoadError:function(arguments){if(typeof(OnLoadError)=='function'){OnLoadError('" + sysField.Name + "','" + valueField + "','" + textField + "',arguments);}}";
                        if (field.IsMultiSelect.HasValue && field.IsMultiSelect.Value)
                        {
                            inputOptions += ",multiple:true";
                        }
                        inputOptions += "\"";
                        sb.AppendFormat("<input id=\"{0}\" name=\"{0}\" style=\"width:{1};\" class=\"{4}\" value=\"{2}\" {3}/>",
                             field.Sys_FieldName, inputWidthStr, value.ObjToStr(), inputOptions, className);
                        #endregion
                    }
                    break;
                case ControlTypeEnum.IconBox: //图标控件
                    {
                        #region 图标控件
                        if (isSearchForm)
                        {
                            sb.AppendFormat("<input id=\"{0}\" name=\"{0}\" class=\"easyui-textbox\" value=\"{1}\" style=\"width:{2};\" />",
                            field.Sys_FieldName, value.ObjToStr(), inputWidthStr);
                        }
                        else
                        {
                            sb.AppendFormat("<input id=\"{0}\" name=\"{0}\" type=\"hidden\" value=\"{1}\" />", field.Sys_FieldName, value.ObjToStr());
                            string iconUrl = SystemOperate.GetIconUrl(value.ObjToStr());
                            if (string.IsNullOrWhiteSpace(iconUrl))
                            {
                                iconUrl = "/Scripts/jquery-easyui/themes/icons/large_picture.png";
                            }
                            sb.AppendFormat("<div style=\"width:100%;height:100%;border:1px solid #95b8e7;\"><img id=\"img_{0}\" style=\"height:100%;border:0px none;\" src=\"{1}\" />", field.Sys_FieldName, iconUrl);
                            sb.AppendFormat("<a style=\"float:right;\" class=\"easyui-linkbutton\" iconCls=\"eu-icon-search\" onclick=\"SelectIcon(this)\" plain=\"true\" iconControlId=\"{0}\">选择图标</a>", field.Sys_FieldName);
                            sb.Append("</div>");
                        }
                        #endregion
                    }
                    break;
                case ControlTypeEnum.ImageUpload: //图片上传控件
                    {
                        #region 图片上传控件
                        if (!isSearchForm)
                        {
                            sb.AppendFormat("<input id=\"{0}\" name=\"{0}\" type=\"hidden\" value=\"{1}\" />", field.Sys_FieldName, value.ObjToStr());
                            string iconPath = value.ObjToStr();
                            if (string.IsNullOrWhiteSpace(iconPath))
                            {
                                iconPath = "/Scripts/jquery-easyui/themes/icons/large_picture.png";
                            }
                            sb.AppendFormat("<div style=\"width:100%;height:100%;border:1px solid #95b8e7;\"><img id=\"img_{0}\" style=\"height:100%;border:0px none;\" src=\"{1}\" />", field.Sys_FieldName, iconPath);
                            sb.AppendFormat("<iframe id=\"iframe_{0}\" src=\"/Page/ImgUploadForm.html?\" style=\"display:none\" onload=\"ImgUploadIframeLoaded('{0}')\"></iframe>", field.Sys_FieldName);
                            sb.AppendFormat("<a id=\"a_{0}\" style=\"float:right;\" class=\"easyui-linkbutton\" data-options=\"disabled:true\" iconCls=\"eu-icon-search\" onclick=\"SelectImage(this)\" plain=\"true\" imgControlId=\"{0}\">选择图片</a>", field.Sys_FieldName);
                            sb.Append("</div>");
                        }
                        #endregion
                    }
                    break;
                case ControlTypeEnum.LabelBox: //查看控件
                    {
                        sb.AppendFormat("<input id=\"{0}\" name=\"{0}\" class=\"easyui-textbox\" style=\"width:100%;\" value=\"{1}\" data-options=\"disabled:true\" />", field.Sys_FieldName, value.ObjToStr());
                    }
                    break;
            }
            #endregion
            if (sb.ToString().Length > 0 && !string.IsNullOrEmpty(field.FieldHelp) &&
                field.ControlTypeOfEnum != ControlTypeEnum.LabelBox && !isSearchForm)
            {
                string tempDataOption = string.Format("title:'{0}'", field.FieldHelp);
                string linkHelp = string.Format("<a id=\"linkHelp_{0}\" class=\"easyui-linkbutton\" iconCls=\"eu-icon-help\" onclick=\"ShowFieldHelp(this)\" plain=\"true\" data-options=\"{1}\"></a>",
                    field.Id, tempDataOption);
                sb.Append(linkHelp);
            }
            #endregion

            return sb.ToString();
        }

        /// <summary>
        /// 附件信息列表HTML
        /// </summary>
        /// <param name="moduleId">模块Id</param>
        /// <param name="id">记录Id</param>
        /// <param name="formType">表单类型</param>
        /// <param name="attachStyle">附件显示方式，默认为简单方式</param>
        /// <returns></returns>
        public static string GetAttachmentListHTML(Sys_Module module, Guid? id, FormTypeEnum formType)
        {
            if (!module.IsEnableAttachment) //未启用附件时返回空
            {
                return string.Empty;
            }
            string errMsg = string.Empty;
            //取附件数据
            List<Sys_Attachment> attachList = new List<Sys_Attachment>();
            string attachFileJson = string.Empty;
            if (id.HasValue && id.Value != Guid.Empty)
            {
                attachList = CommonOperate.GetEntities<Sys_Attachment>(out errMsg, x => x.Sys_ModuleId == module.Id && x.RecordId == id.Value, string.Empty, false, new List<string>() { "Id" }, new List<bool>() { false });
                if (attachList != null && attachList.Count > 0)
                {
                    List<AttachFileInfo> attachFileInfos = attachList.Select(x => new AttachFileInfo()
                    {
                        Id = x.Id.ToString(),
                        AttachFile = string.Format("~/{0}", x.FileUrl),
                        PdfFile = string.Format("~/{0}", x.PdfUrl),
                        SwfFile = string.Format("~/{0}", x.SwfUrl),
                        FileName = x.FileName,
                        FileType = x.FileType,
                        FileSize = x.FileSize,
                        FileDes = x.FileDes
                    }).ToList();
                    attachFileJson = HttpUtility.UrlEncode(JsonHelper.Serialize(attachFileInfos).Replace("\r\n", string.Empty), Encoding.UTF8).Replace("+", "%20");
                    foreach (Sys_Attachment attach in attachList)
                    {
                        attach.FileUrl = string.Format("{0}{1}", Globals.GetBaseUrl(), attach.FileUrl);
                        attach.PdfUrl = string.IsNullOrEmpty(attach.PdfUrl) ? string.Empty : string.Format("{0}{1}", Globals.GetBaseUrl(), attach.PdfUrl);
                        attach.SwfUrl = string.IsNullOrEmpty(attach.SwfUrl) ? string.Empty : string.Format("{0}{1}", Globals.GetBaseUrl(), attach.SwfUrl);
                    }
                }
            }
            //组装html
            StringBuilder sb = new StringBuilder();
            sb.Append("<script type=\"text/javascript\" src=\"/Scripts/common/Attachment.js\"></script>");
            sb.AppendFormat("<input id=\"attachFile\" type=\"hidden\" value=\"{0}\" />", attachFileJson);
            if (module.FormAttachDisplayStyleOfEnum == FormAttachDisplayStyleEnum.GridStype) //列表方式显示
            {
                Guid attachModuleId = SystemOperate.GetModuleIdByName("附件信息");
                List<Sys_GridField> attachGridFields = SystemOperate.GetDefaultGridFields(attachModuleId);
                if (attachGridFields == null) attachGridFields = new List<Sys_GridField>();
                List<string> displayFields = new List<string>() { "FileName", "FileType", "FileSize", "CreateUserName", "CreateDate" };
                sb.Append("<div id=\"attachPanel\" class=\"easyui-panel\" title=\"附件信息\" style=\"width:100%;height:200px;padding:5px;\" data-options=\"collapsible:true\">");
                string gridOptions = "pagination:false,idField:'Id',rownumbers:true,collapsible:true,fitColumns:false,singleSelect:true,toolbar:'#attach_toolbar'";
                sb.AppendFormat("<table id=\"attachGrid\" class=\"easyui-datagrid\" data-options=\"{0}\">", gridOptions);
                sb.Append("<thead>");
                sb.Append("<tr>");
                sb.Append("<th data-options=\"title:'ID',field:'Id',checkbox:true\">ID</th>");
                sb.Append("<th data-options=\"title:'操作',field:'ActionField',width:80,align:'center'\">操作</th>");
                //加载网格字段
                foreach (Sys_GridField field in attachGridFields)
                {
                    if (!field.Sys_FieldId.HasValue || !displayFields.Contains(field.Sys_FieldName)) continue;
                    int fieldWidth = field.Width.HasValue ? field.Width.Value : 120;
                    sb.Append("<th data-options=\"title:'" + field.Display + "',field:'" + field.Sys_FieldName + "',width:" + fieldWidth + ",align:'" + field.Align + "'\">" + field.Display + "</th>");
                }
                sb.Append("</tr>");
                sb.Append("</thead>");
                sb.Append("<tbody>");
                foreach (Sys_Attachment attchement in attachList)
                {
                    //行操作链接
                    string action = string.Format("<a href=\"javascript:DelAttachRow({0},'{1}')\">删除</a>", attchement.Id, attchement.FileName);
                    if (formType == FormTypeEnum.ViewForm) //查看页面
                    {
                        action += string.Format("&nbsp;&nbsp;<a href=\"javascript:DownloadAttach({0})\">下载</a>", attchement.Id);
                    }
                    //构造链接文件名
                    string tempUrl = attchement.FileUrl;
                    if (!string.IsNullOrWhiteSpace(attchement.SwfUrl))
                        tempUrl = string.Format("/Page/DocView.html?fn={0}&swfUrl={1}", HttpUtility.UrlEncode(attchement.FileName), HttpUtility.UrlEncode(attchement.SwfUrl));
                    string tempFileName = string.Format("<a target='_blank' href='{0}'>{1}</a>", tempUrl, attchement.FileName);
                    sb.Append("<tr>");
                    sb.AppendFormat("<td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td><td>{5}</td><td>{6}</td>",
                                 attchement.Id, action, tempFileName, attchement.FileType, attchement.FileSize, attchement.CreateUserName, attchement.CreateDate.HasValue ? attchement.CreateDate.Value.ToString("yyyy-MM-dd HH:mm:ss") : string.Empty);
                    sb.Append("</tr>");
                }
                sb.Append("</tbody>");
                sb.Append("</table>");
                //工具栏
                sb.Append("<div id=\"attach_toolbar\" class=\"toolbar datagrid-toolbar\" style=\"height:27px;\">");
                sb.Append("<a id=\"btnUploadAttach\" class=\"easyui-linkbutton\" iconCls=\"eu-icon-add\" onclick=\"UploadFile(this)\" plain=\"true\" moduleId=\"" + module.Id + "\" moduleName=\"" + module.Name + "\" attachDisplayStyle=\"1\">上传</a>");
                sb.Append("<a id=\"btnDelAttach\" class=\"easyui-linkbutton\" iconCls=\"eu-icon-del\" onclick=\"DelAttach()\" plain=\"true\" moduleId=\"" + module.Id + "\" moduleName=\"" + module.Name + "\" attachDisplayStyle=\"1\">删除</a>");
                sb.Append("</div>");
                sb.Append("</div>");
            }
            else //简单方式
            {
                string btnClass = "easyui-linkbutton";
                string panelClass = "easyui-panel";
                string btnOptions = string.Format("moduleId=\"{0}\" moduleName=\"{1}\" attachDisplayStyle=\"0\"", module.Id, module.Name);
                string panelOptions = "data-options=\"collapsible:true\"";
                sb.AppendFormat("<a id=\"btnAddAttach\" class=\"{0}\" plain=\"true\" iconCls=\"eu-icon-add\" onclick=\"UploadFile(this)\" {1}>上传附件</a>", btnClass, btnOptions);
                sb.AppendFormat("<div class=\"{0}\" title=\"附件信息\" style=\"width:100%;height:74px;\" {1}>", panelClass, panelOptions);
                sb.Append("<div id=\"attachPanel\">");
                if (attachList != null && attachList.Count > 0)
                {
                    foreach (Sys_Attachment attach in attachList)
                    {
                        string tempUrl = attach.FileUrl;
                        if (!string.IsNullOrEmpty(attach.SwfUrl))
                        {
                            tempUrl = string.Format("/Page/DocView.html?fn={0}&swfUrl={1}", HttpUtility.UrlEncode(attach.FileName).Replace("+", "%20"), HttpUtility.UrlEncode(attach.SwfUrl).Replace("+", "%20"));
                        }
                        sb.AppendFormat("<a id='btn_file_{0}' target='_blank' href='{1}'>{2}</a>", attach.Id, tempUrl, attach.FileName);
                        string styleStr = formType == FormTypeEnum.EditForm ? " style=\"margin-right:10px;\"" : string.Empty;
                        string btnAttr = string.Empty;
                        btnAttr = string.Format("AttachId=\"{0}\" FileName=\"{1}\"", attach.Id.ToString(), attach.FileName);
                        sb.Append("<a id=\"btn_remove_" + attach.Id.ToString() + "\" " + styleStr + " class=\"" + btnClass + "\" plain=\"true\" iconCls=\"eu-icon-del\" onclick=\"DelAttach(this)\" " + btnAttr + "></a>");
                        if (formType == FormTypeEnum.ViewForm)
                        {
                            sb.Append("<a id=\"btn_download_" + attach.Id.ToString() + "\" style=\"margin-right:10px;\" class=\"" + btnClass + "\" plain=\"true\" iconCls=\"eu-icon-arrow_down\" onclick=\"window.open( '/Annex/DownloadAttachment.html?attachId=" + attach.Id + "')\"></a>");
                        }
                    }
                }
                sb.Append("</div>");
                sb.Append("</div>");
            }
            return sb.ToString();
        }

        /// <summary>
        /// 获取审批信息和审批意见页面HTML
        /// </summary>
        /// <param name="moduleId">模块ID</param>
        /// <param name="id">记录ID</param>
        /// <param name="todoTaskId">待办任务ID</param>
        /// <returns></returns>
        public static string GetApprovalInfoAndOpinionsHtml(Guid moduleId, Guid? id, Guid? todoTaskId)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<div id=\"approvalDiv\">");
            bool isDisplayOpinionPanel = todoTaskId.HasValue && todoTaskId.Value != Guid.Empty && BpmOperate.IsCurrentToDoTaskHandler(todoTaskId.Value, UserInfo.CurrentUserInfo);
            if (id.HasValue && id.Value != Guid.Empty)
            {
                List<ApprovalInfo> approvalInfos = todoTaskId.HasValue && todoTaskId.Value != Guid.Empty ? BpmOperate.GetRecordApprovalInfosByTodoId(todoTaskId.Value) : BpmOperate.GetModuleRecordApprovalInfos(moduleId, id.Value);
                var group = approvalInfos.GroupBy(x => x.NodeName).ToList();
                string mergeCount = string.Empty;
                string mergeIndex = string.Empty;
                foreach (var infos in group)
                {
                    int count = infos.Count();
                    if (count > 1)
                    {
                        if (mergeCount != string.Empty)
                            mergeCount += ",";
                        mergeCount += count;
                        ApprovalInfo info = infos.FirstOrDefault();
                        int tbIndex = approvalInfos.IndexOf(info);
                        if (mergeIndex != string.Empty)
                            mergeIndex += ",";
                        mergeIndex += tbIndex;
                    }
                }
                sb.Append("<div style=\"padding-bottom:2px;\">");
                sb.AppendFormat("<div id=\"div_ApprovalList\" mergeCount=\"{0}\" mergeIndex=\"{1}\" style=\"padding:5px;\" class=\"easyui-panel\" title=\"审批记录\" data-options=\"iconCls:'eu-icon-approvalok',collapsible:true\">", mergeCount, mergeIndex);
                sb.Append("<table id=\"tb_approvalList\" class=\"easyui-datagrid\" data-options=\"onSelect:function(rowIndex, rowData){$('#tb_approvalList').datagrid('unselectAll');}\">");
                sb.Append("<thead>");
                sb.Append("<tr>");
                sb.Append("<th data-options=\"field:'NodeName',width:120\">节点名称</th>");
                sb.Append("<th data-options=\"field:'Handler',width:80\">处理人</th>");
                sb.Append("<th data-options=\"field:'HandleResult',width:80\">处理结果</th>");
                sb.Append("<th data-options=\"field:'HandleTime',width:150\">处理时间</th>");
                sb.Append("<th data-options=\"field:'ApprovalOpinions',width:250\">处理意见</th>");
                sb.Append("<th data-options=\"field:'NextNodeName',width:120\">下一节点</th>");
                sb.Append("<th data-options=\"field:'NextHandler',width:150\">下一处理人</th>");
                sb.Append("</tr>");
                sb.Append("</thead>");
                sb.Append("<tbody>");
                foreach (var info in approvalInfos)
                {
                    sb.Append("<tr>");
                    sb.AppendFormat("<td>{0}</td>", info.NodeName);
                    sb.AppendFormat("<td>{0}</td>", info.Handler);
                    sb.AppendFormat("<td>{0}</td>", info.HandleResult);
                    sb.AppendFormat("<td>{0}</td>", info.HandleTime);
                    sb.AppendFormat("<td>{0}</td>", info.ApprovalOpinions);
                    sb.AppendFormat("<td>{0}</td>", info.NextNodeName);
                    sb.AppendFormat("<td>{0}</td>", info.NextHandler);
                    sb.Append("</tr>");
                }
                sb.Append("</tbody>");
                sb.Append("</table>");
                sb.Append("</div>");
                sb.Append("</div>");
            }
            if (isDisplayOpinionPanel)
            {
                Bpm_WorkNode currNode = BpmOperate.GetCurrentApprovalNode(todoTaskId.Value);
                UserInfo currUser = UserInfo.CurrentUserInfo;
                sb.Append("<div style=\"padding-bottom:2px;\">");
                sb.Append("<div class=\"easyui-panel\" title=\"审批意见\" style=\"padding-bottom:5px;\" data-options=\"iconCls:'eu-icon-edit',collapsible:true\">");
                sb.Append("<table style=\"line-height:30px;\">");
                sb.Append("<tr>");
                sb.Append("<td style=\"width: 100px;\">");
                sb.Append("<span style=\"margin-left: 13px;\">审批节点：</span>");
                sb.Append("</td>");
                sb.Append("<td>");
                sb.AppendFormat("<span style=\"width: 200px; line-height: 25px; text-align:left;\" class=\"left\">{0}</span>", currNode != null ? currNode.Name : string.Empty);
                sb.Append("</td>");
                sb.Append("<td style=\"width: 100px;\">");
                sb.Append("<span>审批人员：</span>");
                sb.Append("</td>");
                sb.Append("<td>");
                sb.AppendFormat("<span style=\"width: 200px; line-height: 25px; text-align:left;\" class=\"left\">{0}</span>", currUser != null ? currUser.EmpName : string.Empty);
                sb.Append("</td>");
                sb.Append("</tr>");
                sb.Append("<tr>");
                sb.Append("<td style=\"width: 100px;\">");
                sb.Append("<span style=\"margin-left: 13px;\">审批意见：</span>");
                sb.Append("</td>");
                sb.Append("<td colspan=\"3\">");
                sb.Append("<input id=\"txt_approvalOpinions\" class=\"easyui-textbox\" data-options=\"multiline:true,prompt:'请填写处理意见！'\" style=\"width:600px;height:120px\" />");
                sb.Append("</td>");
                sb.Append("</tr>");
                sb.Append("</table>");
                sb.Append("</div>");
                sb.Append("</div>");
            }
            else
            {
                sb.Append("<div style=\"padding-bottom:2px\">&nbsp;</div>");
            }
            sb.Append("</div>");
            sb.Append("<script type=\"text/javascript\" src=\"/Scripts/Bpm/ApprovalInfo.js\"></script>");
            return sb.ToString();
        }

        /// <summary>
        /// 获取表单按钮HTML
        /// </summary>
        /// <param name="module">模块</param>
        /// <param name="buttons">按钮集合</param>
        /// <param name="editMode">编辑模式</param>
        /// <param name="gridId">网格domid</param>
        /// <param name="id">记录ID</param>
        /// <param name="titleKeyValue">titleKeyValue</param>
        /// <returns></returns>
        public static string GetFormButtonHTML(Sys_Module module, List<FormButton> buttons, int editMode, string gridId, Guid? id = null, string titleKeyValue = null)
        {
            StringBuilder formBtnSb = new StringBuilder();
            if (buttons != null && buttons.Count > 0)
            {
                string btnCls = string.Empty;
                string btnWidth = "90%";
                if (editMode == (int)ModuleEditModeEnum.PopFormEdit)
                {
                    btnWidth = "100%";
                }
                formBtnSb.AppendFormat("<div id=\"divFormBtn\" style=\"width:{0};height:30px;line-height:30px;text-align:center;margin-left:-3px;margin-top:8px;\">", btnWidth);
                int no = 0;
                foreach (FormButton btn in buttons)
                {
                    if (editMode == (int)ModuleEditModeEnum.GridRowBottomFormEdit && (btn.DisplayText == "保存并新增" || btn.DisplayText == "关闭"))
                        continue;
                    no++;
                    string tagId = string.Format("btn_{0}", new Random().Next(100));
                    if (!string.IsNullOrEmpty(btn.TagId))
                    {
                        tagId = btn.TagId;
                    }
                    string icon = btn.Icon;
                    switch (btn.IconType)
                    {
                        case ButtonIconType.Edit:
                            if (btn.DisplayText == "编辑" && id.HasValue && id.Value != Guid.Empty)
                            {
                                bool canEdit = PermissionOperate.UserHasOperateRecordPermission(UserInfo.CurrentUserInfo.UserId, module.Id, id.Value, DataPermissionTypeEnum.EditData);
                                if (!canEdit) continue;
                            }
                            icon = "eu-icon-edit";
                            break;
                        case ButtonIconType.Close:
                            icon = "eu-icon-close";
                            break;
                    }
                    string c = string.Empty;
                    if (GlobalSet.IsShowStyleBtn)
                        c = string.Format(" c{0}", no % 9);
                    formBtnSb.Append("<a id=\"" + tagId + "\" class=\"easyui-linkbutton" + c + "\" style=\"margin-right:5px;\" iconCls=\"" + icon + "\" onclick=\"" + (string.IsNullOrEmpty(btn.ClickMethod) ? string.Empty : btn.ClickMethod) + "\"");
                    if (btn.IconType == ButtonIconType.DraftRelease) //草稿发布按钮
                    {
                        formBtnSb.Append(" release=1");
                    }
                    formBtnSb.Append(" detail=\"" + (module.ParentId.HasValue && module.ParentId.Value != Guid.Empty ? "true" : "false") + "\" editMode=\"" + editMode + "\" moduleId=\"" + module.Id + "\" moduleName=\"" + module.Name + "\" gridId=\"" + (string.IsNullOrEmpty(gridId) ? string.Empty : gridId) + "\"");
                    if (!string.IsNullOrEmpty(titleKeyValue))
                        formBtnSb.Append(" titleKeyValue=\"" + titleKeyValue + "\"");
                    formBtnSb.Append(">" + (string.IsNullOrEmpty(btn.DisplayText) ? string.Empty : btn.DisplayText) + "</a>");
                }
                formBtnSb.Append("</div>");
            }
            return formBtnSb.ToString();
        }

        /// <summary>
        /// 获取表单tooltags的html
        /// </summary>
        /// <param name="toolTags">工具标签按钮集合</param>
        /// <returns></returns>
        public static string GetFormToolTagsHTML(Sys_Module module, Guid? id, List<FormToolTag> toolTags)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<div id=\"div_tags\" style=\"text-align:right;margin-right:5px;\">");
            if (toolTags != null && toolTags.Count > 0 && module != null)
            {
                foreach (FormToolTag tag in toolTags)
                {
                    sb.AppendFormat("<a id=\"{0}\" style=\"margin-right:2px;\" href=\"#\" title=\"{2}\" class=\"easyui-linkbutton easyui-tooltip\" data-options=\"plain:true,iconCls:'{3}'\" onclick=\"{4}\" moduleId=\"{5}\" moduleName=\"{6}\" recordId=\"{7}\">{1}</a>",
                        tag.TagId, tag.Text, string.IsNullOrEmpty(tag.Title) ? tag.Text : tag.Title, tag.Icon, tag.ClickMethod, module.Id, module.Name, id.HasValue && id.Value != Guid.Empty ? id.Value.ToString() : string.Empty);
                }
            }
            sb.Append("</div>");
            return sb.ToString();
        }

        #endregion
    }
}
